#pragma once


#include<string>
#include<iostream>

using namespace std;

namespace yyh
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _prev;
		list_node<T>* _next;
		
		list_node(const T& data = T())
			:_data(data)
			,_prev(nullptr)
			,_next(nullptr)
		{ }
	};

	template<class T, class Ptr, class Ref>
	struct list_iterator
	{
		typedef list_node<T> Node;
		typedef list_iterator<T, Ptr, Ref> Self;
		
		Node* _node;

		list_iterator(Node* node)
			:_node(node)
		{ }

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		Self operator++()
		{
			_node = _node->_next;
			return *this;
		}

		bool operator!=(const Self& s)
		{
			return _node != s._node;
		}

		bool operator==(const Self& s)
		{
			return _node == s._node;
		}
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node;
	public:
		typedef list_iterator<T, T*, T&> iterator;

		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		void empty_init()
		{
			_head = new Node;
			_head->_prev = _head->_next = _head;
		}

		list()
		{
			empty_init();
		}

		void push_back(const T& data)
		{
			Node* new_node = new Node(data);
			Node* cur = _head;
			while (cur->_next)
			{
				cur = cur->_next;
			}
			cur->_next = new_node;
			_size++;
		}

		void insert()
		{

		}

	private:
		Node* _head;
		size_t _size;
	};

	void test1()
	{
		list<string> lt;
		lt.push_back("one");
		lt.push_back("two");
		lt.push_back("three");
		lt.push_back("four");
		list<string>::iterator it = lt.begin();
		while (it != lt.end())
		{
			cout << *it << ' ';
			++it;
		}
		cout << endl;
	}
}